﻿using com.nm.ApiServer;
using com.nm.ApiServer.Attributes;
using com.nm.Attributes;
using com.nm.db.Models.Hkerp;
using com.nm.db.Models.Systems;
using CsrdAPI.Common;
using CsrdAPI.model.BalanceData;
using EntityFramework.Extensions;
using george.Data;
using george.Helper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CsrdAPI.Csrd;

namespace CsrdAPI
{
    [Description("结算管理")]
    public class BalanceHandler : BaseHandler
    {
        #region 结算查询
        [MustLogin]
        [JsonType]
        [Description("结算查询")]
        [ReturnType(typeof(PaperData<ListData>))]
        public ApiResult GetBalaceList([ParamDescription("查询条件")] SearchData param)
        {
            if (param == null) return Error("参数对象为空！");
            if (string.IsNullOrWhiteSpace(param.CompanyID)) return Error("品牌不能为空！");
            if (string.IsNullOrWhiteSpace(param.BalanceDate)) return Error("结算日期不能为空！");
            var shopStrList = ShopHelper.ShopParamStr(param.BalanceDate);
            var dc = new HKERPEntities();
            var saleList = dc.Database.SqlQuery<ReturnData>($@"exec KM_GetBalance_Data '{param.CompanyID}','{param.BalanceDate}','{shopStrList}','{param.ShopStr}'").ToList().GroupBy(d => d.ShopID);

            var newList = saleList.Select(d => new ReturnData()
            {
                ShopID = d.Key,
                ShopCode = d.First().ShopCode,
                BalanceDate = d.First().BalanceDate,
                ShopName = d.First().ShopName,
                CompanyID = d.First().CompanyID,
                Qty = d.Sum(r => r.Qty),
                RealAmount = d.Sum(r => r.RealAmount),
            });
            var csrd = new CsrdEntities();
            var query = (from c in newList
                         join b in csrd.Csrd_Client on c.ShopID equals b.ShopID
                         select new
                         {
                             c,
                             b.Discount,
                             BalanceAmount = b.Discount * c.RealAmount,
                             BalaceSate = (from s in csrd.Csrd_Balance
                                           where s.ShopID == c.ShopID && s.BalanceDate == c.BalanceDate
                                           select s.BlanceState).FirstOrDefault() ?? false,
                             BalanceCode = (from s in csrd.Csrd_Balance
                                            where s.ShopID == c.ShopID && s.BalanceDate == c.BalanceDate
                                            select s.BalanceCode).FirstOrDefault()
                         });
            if (param.SateID != -1)
            {
                query = query.Where(t => t.BalaceSate == (param.SateID != 0));
            }
            var result = PaperData<ListData>.Create(query.Count(), param.Size, param.Page);
            result.Items = query.OrderByDescending(t => t.c.ShopCode)
                .Skip(result.Skip)
                .Take(result.Limt).ToList().Select(o => new ListData
                {
                    CompanyID = o.c.CompanyID,
                    ShopID = o.c.ShopID,
                    ShopCode = o.c.ShopCode,
                    ShopName = o.c.ShopName,
                    Discount = o.Discount,
                    RealAmount = o.c.RealAmount,
                    Qty = o.c.Qty,
                    BalanceAmount = Math.Round(o.BalanceAmount, 2),
                    BalanceDate = o.c.BalanceDate,
                    BalaceSate = o.BalaceSate,
                    BalanceCode = o.BalanceCode
                }).ToList();
            //SB+年月+KM+流水号（十三位数）
            var ss = "";
            var i = 1;
            var _BalanceCode = "";
            //后台找出当月最大
            var MaxCode = csrd.Csrd_Balance.Where(t => t.BalanceDate == param.BalanceDate).Max(o => o.BalanceCode);
            if (!string.IsNullOrWhiteSpace(MaxCode))
            {
                i = Convert.ToInt32(StringHelper.Right(MaxCode, 3)) + 1;
            }
            foreach (var item in result.Items)
            {
                if (string.IsNullOrWhiteSpace(item.BalanceCode))
                {
                    ss = StringHelper.Right("000" + i, 3);
                    _BalanceCode = ("SB" + param.BalanceDate.Replace("-", "") + param.CompanyID + ss).ToUpper();
                    item.BalanceCode = _BalanceCode;
                }
                i++;
            }
            var tran = csrd.Database.BeginTransaction();
            //csrd.Csrd_Balance.Delete(t => t.CompanyID == param.CompanyID && t.BalanceDate == param.BalanceDate && t.BlanceState == false);
            foreach (var item in result.Items)
            {
                if (!csrd.Csrd_Balance.Any(t => t.BalanceCode == item.BalanceCode))
                {
                    var add = new Csrd_Balance
                    {
                        CompanyID = item.CompanyID,
                        BalanceCode = item.BalanceCode,
                        BalanceDate = item.BalanceDate,
                        BlanceAmount = item.BalanceAmount,
                        BlanceState = item.BalaceSate,
                        Discount = item.Discount,
                        ShopID = item.ShopID,
                        SaleAmount = item.RealAmount,
                        SaleQty = item.Qty,
                        CreateDate = DateTime.Now
                    };
                    csrd.Csrd_Balance.Add(add);
                }
            }
            try
            {
                csrd.SaveChanges();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                return Error(ex.Message);
            }
            return Success(result);
        }
        #endregion

        #region 结算处理
        [MustLogin]
        [JsonType]
        [Description("结算处理")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult Baleance(BalanceParam param)
        {
            if (string.IsNullOrWhiteSpace(param.CompanyID)) return Error("品牌不能为空！");
            if (string.IsNullOrWhiteSpace(param.BalanceDate)) return Error("结算日期不能为空！");
            if (string.IsNullOrWhiteSpace(param.ShopList)) return Error("参数不能为空！");
            
            var dc = new CsrdEntities();
            var tran = dc.Database.BeginTransaction();

            var list = param.ShopList.Split(',');
            foreach (var s in list)
            {
                var balance = dc.Csrd_Balance.FirstOrDefault(t => t.ShopID == s && t.BalanceDate == param.BalanceDate);
                if (balance == null) continue;
                balance.BlanceState = param.IsBalance;
                balance.Operator = this.UserId;
                balance.OperationDate = DateTime.Now;
            }
            try
            {
                dc.SaveChanges();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                return Error(ex.Message);
            }
            return Success(0);
        }
        #endregion


        #region 打印明细数据
        [MustLogin]
        [Description("打印明细数据")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult GetBalaceDtl([ParamDescription("店铺ID")]string ShopID, string CompanyID, string BalanceDate)
        {
            if (string.IsNullOrWhiteSpace(CompanyID)) return Error("品牌ID不能为空！");
            if (string.IsNullOrWhiteSpace(ShopID)) return Error("店铺ID不能为空！");
            if (string.IsNullOrWhiteSpace(BalanceDate)) return Error("结算日期不能为空！");
            var dc = new CsrdEntities();
            var query = (from c in dc.Csrd_Balance
                         join b in dc.Csrd_Client on c.ShopID equals b.ShopID
                         where c.ShopID == ShopID && c.CompanyID == CompanyID && c.BalanceDate == BalanceDate
                         select new
                         {
                             c,
                             b.Discount
                         }).FirstOrDefault();
            if (query == null) return Error("没有结算不能打印！");
            var result = new PrintData
            {
                BalanceCode = query.c.BalanceCode,
                BalanceDate = query.c.BalanceDate,
                Discount = query.Discount,
                RealAmount = query.c.SaleAmount,
                Qty = query.c.SaleQty ?? 0,
                BalanceAmount = query.c.BlanceAmount,
                TaxRate = 0.06,
                TaxFreeAmount = Math.Round(Convert.ToDouble(query.c.BlanceAmount) / (1 + 0.06), 2),
                TaxAmount = Math.Round((Convert.ToDouble(query.c.BlanceAmount) / (1 + 0.06)) * 0.06, 2),
                CreateDate = DateTime.Now.ToShortDateString()
            };
            return Success(result);
        }
        #endregion


        #region 根据店铺ID获取客户资料
        [MustLogin]
        [Description("根据店铺ID获取客户资料")]
        [ReturnType(typeof(ClientData))]
        public ApiResult GetClient([ParamDescription("店铺ID")]string ShopID)
        {
            if (string.IsNullOrWhiteSpace(ShopID)) return Error("店铺ID不能为空！");
            var dc = new CsrdEntities();
            var query = dc.Csrd_Client.FirstOrDefault(t => t.ShopID == ShopID);
            var result = new ClientData
            {
                ClientCode = query.ClientCode,
                RegistName = query.RegistName,
                RegistCode = query.RegistCode,
                RedistAddress = query.RedistAddress,
                AccountCode = query.AccountCode,
                BankName = query.BankName,
                ShopLinkMan = query.ShopLinkMan,
                ShopTelePhone = query.ShopTelePhone,
                ContractState =query.ContractState,
                ContractCode = query.ContractCode
            };
            return Success(result);
        }
        #endregion


        #region 结算图表
        [MustLogin]
        [Description("首页结算图表")]
        [ReturnType(typeof(IList<ChartModel>))]
        public ApiResult GetBalance()
        {
            string[] Months = new string[6];
            for (int i = 0; i < 6; i++)
            {
                //Months[i] = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).AddMonths(-i - 1).ToString("yyyy-MM");
                Months[i] = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).AddMonths(-i - 1).ToString("yyyy-MM");
            }
            var dc = new CsrdEntities();
            var query = dc.Csrd_Balance.Where(t => Months.Contains(t.BalanceDate)).ToList().GroupBy(o => o.BalanceDate);

            List<ChartModel> result2 = new List<ChartModel>();
            if (!query.Any())
            {
                for (int i = 0; i < Months.Length; i++)
                {
                    ChartModel cm = new ChartModel();
                    cm.BalanceDate = Months[i].ToString();
                    cm.BalanceAmount = 0;
                    result2.Add(cm);
                }
                //排序
                var q = from r in result2
                            orderby r.BalanceDate ascending /*descending*/
                            select r;
                
                var temp = q.ToList().Select(o => new ChartModel
                {
                    BalanceDate = o.BalanceDate,
                    BalanceAmount = o.BalanceAmount
                }).ToList();
                result2 = temp;
            }
            else
            {
                var result = query.Select(t => new ChartModel
                {
                    BalanceDate = t.Key,
                    BalanceAmount = t.Sum(o => o.BlanceState == false ? 0 : o.BlanceAmount)
                }).ToList().OrderBy(t => t.BalanceDate);
                result2 = result.ToList();

                if (result2.Count != 6)
                {
                    //初始化六个月的结算数据
                    List<ChartModel> result3 = new List<ChartModel>();
                    for (int i = 0; i < Months.Length; i++)
                    {
                        ChartModel cm = new ChartModel();
                        cm.BalanceDate = Months[i].ToString();
                        cm.BalanceAmount = 0;
                        result3.Add(cm);
                    }
                    //左连接
                    var que = from s in result3
                                join c in result2
                                on s.BalanceDate equals c.BalanceDate into gc
                                from gci in gc.DefaultIfEmpty()
                                select new
                                {
                                    BalanceDate = s.BalanceDate,
                                    BalanceAmount = gci == null ? 0 : gci.BalanceAmount
                                };
                    //返回List结果
                    var result4 = que.ToList().Select(o => new ChartModel
                    {
                        BalanceDate = o.BalanceDate,
                        BalanceAmount = o.BalanceAmount,
                    }).ToList();
                    result2 = result4;
                }                
                //排序
                var q = from r in result2
                        orderby r.BalanceDate ascending /*descending*/
                        select r;

                var temp = q.ToList().Select(o => new ChartModel
                {
                    BalanceDate = o.BalanceDate,
                    BalanceAmount = o.BalanceAmount
                }).ToList();
                result2 = temp;
            }
            return Success(result2);
        }


        [MustLogin]
        [Description("首页结算图表")]
        [ReturnType(typeof(IList<char>))]
        public ApiResult BalanceCount()
        {
            string[] Months = new string[6];
            for (int i = 0; i < 6; i++)
            {
                Months[i] = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).AddMonths(-i - 1).ToString("yyyy-MM");
            }

            var dc = new CsrdEntities();

            List<ChartCountData> result2 = new List<ChartCountData>();

            var ls2 = from p in dc.Csrd_Balance
                      where Months.Contains(p.BalanceDate)
                      group p by p.BalanceDate
                      into g
                      select new { Key = g.Key, count = g.Count(), NoBalanceCount = g.Sum(item => item.BlanceState == false ? 1 : 0) };
            var query2 = ls2.ToList();

            if (!query2.Any())
            {
                for (int i = 0; i < Months.Length; i++)
                {
                    ChartCountData ccd = new ChartCountData();
                    ccd.BalanceDate = Months[i].ToString();
                    ccd.Balance = 0;
                    ccd.NoBalance = 0;
                    result2.Add(ccd);
                }
                //排序
                var q = from r in result2
                        orderby r.BalanceDate ascending /*descending*/
                        select r;

                var temp = q.ToList().Select(o => new ChartCountData
                {
                    BalanceDate = o.BalanceDate,
                    Balance=o.Balance,
                    NoBalance=o.NoBalance
                }).ToList();
                result2 = temp;
            }
            else
            {
                var result = query2.Select(t => new ChartCountData
                {
                    BalanceDate = t.Key,
                    Balance = Math.Round(1 - (t.NoBalanceCount / Convert.ToDouble(t.count)), 2),
                    NoBalance = Math.Round(t.NoBalanceCount / Convert.ToDouble(t.count), 2),
                }).ToList().OrderBy(t => t.BalanceDate);
                result2 = result.ToList();

                if (result2.Count != 6)
                {
                    List<ChartCountData> result3 = new List<ChartCountData>();
                    for (int i = 0; i < Months.Length; i++)
                    {
                        ChartCountData ccd = new ChartCountData();
                        ccd.BalanceDate = Months[i].ToString();
                        ccd.Balance = 0;
                        ccd.NoBalance = 0;
                        result3.Add(ccd);
                    }
                    var query = from s in result3
                                join c in result2
                                on s.BalanceDate equals c.BalanceDate into gc
                                from gci in gc.DefaultIfEmpty()
                                select new
                                {
                                    BalanceDate = s.BalanceDate,
                                    Balance = gci == null ? 0 : gci.Balance,
                                    NoBalance = gci == null ? 0 : gci.NoBalance,
                                };
                    var result4 = query.ToList().Select(o => new ChartCountData
                    {
                        BalanceDate = o.BalanceDate,
                        Balance = o.Balance,
                        NoBalance = o.NoBalance
                    }).ToList();
                    result2 = result4;
                }
                //排序
                var q = from r in result2
                        orderby r.BalanceDate ascending /*descending*/
                        select r;

                var temp = q.ToList().Select(o => new ChartCountData
                {
                    BalanceDate = o.BalanceDate,
                    Balance = o.Balance,
                    NoBalance = o.NoBalance
                }).ToList();
                result2 = temp;
            }
            return Success(result2);
        }


        #endregion

    }


}
